#include<bits/stdc++.h>
using namespace std;
namespace IO
{
	char buff[1<<21],*p1=buff,*p2=buff;
	char getch(){return p1==p2&&(p2=((p1=buff)+fread(buff,1,1<<21,stdin)),p1==p2)?EOF:*p1++;}
	template<typename T>void read(T &x){char CH=getch();int fl=1;x=0;while(CH>'9'||CH<'0'){if(CH=='-')fl=-1;CH=getch();}while(CH<='9'&&CH>='0'){x=x*10+CH-48;CH=getch();}x*=fl;}
	template<typename T>void read_s(T &x){x="";char CH=getch();while(!(CH>='a'&&CH<='z')&&!(CH>='A'&&CH<='Z'))CH=getch();while((CH>='a'&&CH<='z')||(CH>='A'&&CH<='Z')){x+=CH;CH=getch();}}
	template<typename T,typename ...Args>void read(T &x,Args& ...args){read(x);read(args...);}
	char obuf[1<<21],*p3=obuf;
	void putch(char CH) {if(p3-obuf<(1<<21))*p3++=CH;else fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=CH;}
	char CH[100];
	template<typename T>void write(T x) {if(!x)return putch('0');if(x<0)putch('-'),x*=-1;int top=0;while(x)CH[++top]=x%10+48,x/=10;while(top)putch(CH[top]),top--;}
	template<typename T,typename ...Args>void write(T x,Args ...args) {write(x);putch(' ');write(args...);}
	void put(string s){for(int i=0;i<s.size();i++)putch(s[i]);}
	void flush(){fwrite(obuf,p3-obuf,1,stdout);}
}
using namespace IO;
int n,m;
char a[3005][3005],tmp[3005][3005];
int cnt[3005][3005];
int len[3005];
int sum[3005];
int p[3005][3005];
int ans;
void solve(int x,int x2,int y,int y2)
{
	if(x==x2||y==y2) return;
	int flag=0;
	if(x2-x<y2-y)
	{
		for(int i=x;i<=x2;i++)
			for(int j=y;j<=y2;j++) a[j][x+x2-i]=tmp[i][j];
		flag=1;swap(x,y);swap(x2,y2);
	}
	else for(int i=x;i<=x2;i++) for(int j=y;j<=y2;j++) a[i][j]=tmp[i][j];
	int mid=x+x2>>1;
	for(int i=y;i<=y2;i++) 
	{
		int cur=mid;
		while(a[cur][i]==a[mid][i]&&cur>=x) --cur;++cur;
		len[i]=mid-cur+1;
	}
	for(int i=x;i<=mid;i++)
	{
		p[i][y2+1]=y2;
		for(int j=y2;j>=y;j--)
		{
			if(a[i][j]==a[i][j+1]) p[i][j]=p[i][j+1];
			else p[i][j]=j;
		}
	}
	for(int i=y;i<=y2;i++)
	{
		for(int j=y;j<=y2+1;j++) sum[j]=0;
		for(int j=mid-len[i]+1;j<=mid;j++) ++sum[p[j][i]];
		for(int j=y2;j>=y;j--) sum[j]+=sum[j+1];
		for(int j=i+1;j<=y2;j++) 
		{
			cnt[i][j]=0;
			if(len[i]>len[j]) continue;
			if(a[mid][i]==a[mid][j]) cnt[i][j]+=sum[j]; 
		}
	}
	
	for(int i=x;i<=mid;i++)
	{
		p[i][y-1]=y;
		for(int j=y;j<=y2;j++)
		{
			if(a[i][j]==a[i][j-1]) p[i][j]=p[i][j-1];
			else p[i][j]=j;
		}
	}
	for(int i=y;i<=y2;i++)
	{
		for(int j=y-1;j<=y2;j++) sum[j]=0;
		for(int j=mid-len[i]+1;j<=mid;j++) ++sum[p[j][i]];
		for(int j=y;j<=y2;j++) sum[j]+=sum[j-1];
		for(int j=y;j<i;j++)
		{
			if(len[i]>=len[j]) continue;
			if(a[mid][i]==a[mid][j]) cnt[j][i]+=sum[j]; 
		}
	}
	
	for(int i=y;i<=y2;i++)
	{
		int cur=mid+1;
		while(a[cur][i]==a[mid+1][i]&&cur<=x2) ++cur;--cur;
		len[i]=cur-mid;
	}
	for(int i=mid+1;i<=x2;i++)
	{
		p[i][y2+1]=y2;
		for(int j=y2;j>=y;j--)
		{
			if(a[i][j]==a[i][j+1]) p[i][j]=p[i][j+1];
			else p[i][j]=j;
		}
	}
	for(int i=y;i<=y2;i++)
	{
		for(int j=y;j<=y2+1;j++) sum[j]=0;
		for(int j=mid+1;j<=mid+len[i];j++) ++sum[p[j][i]];
		for(int j=y2;j>=y;j--) sum[j]+=sum[j+1];
		for(int j=i+1;j<=y2;j++) 
		{
			if(len[i]>len[j]) continue;
			if(a[mid+1][i]==a[mid+1][j]&&a[mid+1][i]==a[mid][i]) ans+=cnt[i][j]*sum[j];
		}
	}
	
	for(int i=mid+1;i<=x2;i++)
	{
		p[i][y-1]=y;
		for(int j=y;j<=y2;j++)
		{
			if(a[i][j]==a[i][j-1]) p[i][j]=p[i][j-1];
			else p[i][j]=j;
		}
	}
	for(int i=y;i<=y2;i++)
	{
		for(int j=y-1;j<=y2;j++) sum[j]=0;
		for(int j=mid+1;j<=mid+len[i];j++) ++sum[p[j][i]];
		for(int j=y;j<=y2;j++) sum[j]+=sum[j-1];
		for(int j=y;j<i;j++)
		{
			if(len[i]>=len[j]) continue;
			if(a[mid+1][i]==a[mid+1][j]&&a[mid+1][i]==a[mid][i]) ans+=cnt[j][i]*sum[j];
		}
	}
	if(flag) solve(y,y2,x,mid),solve(y,y2,mid+1,x2);
	else solve(x,mid,y,y2),solve(mid+1,x2,y,y2);
}
int main()
{
	freopen("star.in","r",stdin);
	freopen("star.out","w",stdout);
	read(n,m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			tmp[i][j]=getch();
			while(tmp[i][j]<'a'||tmp[i][j]>'z') tmp[i][j]=getch();
		}
	solve(1,n,1,m);
	write(ans);
	flush();
	return 0;
}
